package com.xyazm.inventory.processor;

import com.xyazm.common.logger.LoggerFormat;
import com.xyazm.common.utils.MdcUtil;
import com.xyazm.inventory.domain.dto.DeductStockDTO;
import com.xyazm.inventory.exception.InventoryBizException;
import com.xyazm.inventory.exception.InventoryErrorCodeEnum;
import com.xyazm.inventory.tcc.ILockMysqlStockTccService;
import com.xyazm.inventory.tcc.ILockRedisStockTccService;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.UUID;

/**
 * 扣减商品库存处理器
 * @author xuyou
 * @date 2022年08月03日 20:31
 */
@Slf4j
@Component
public class DeductProductStockProcessor {


    @Autowired
    private ILockMysqlStockTccService lockMysqlStockTccService;

    @Autowired
    private ILockRedisStockTccService lockRedisStockTccService;

    @Autowired
    private SyncStockToCacheProcessor syncStockToCacheProcessor;

    /**
     * 执行扣减商品库存逻辑
     * @author xuyou
     * 2022/8/3 0003 20:32
     * @param deductStock
    */
    @GlobalTransactional(rollbackFor = Exception.class)
    public void doDeduct(DeductStockDTO deductStock) {

        // 获取当前线程的traceId,如果没有，初始化
        String traceId = MdcUtil.getOrInitTraceId();

        // 1、执行执行mysql库存扣减
        boolean result = lockMysqlStockTccService.deductStock(null,deductStock,traceId);
        if(!result) {
            throw new InventoryBizException(InventoryErrorCodeEnum.PRODUCT_SKU_STOCK_NOT_FOUND_ERROR);
        }

        // 2、执行redis库存扣减
        result = lockRedisStockTccService.deductStock(null,deductStock,traceId);
        if(!result) {
           // 已mysql数据为准
            log.info(LoggerFormat.build()
                    .remark("执行redis库存扣减失败！")
                    .data("deductStock", deductStock)
                    .finish());
            syncStockToCacheProcessor.doSync(deductStock.getSkuCode());
        }
    }
}
